"""
用户认证服务
支持JWT令牌和密码加密
"""

import logging
from datetime import datetime, timedelta
from typing import Optional, Dict, Any
from jose import JWTError, jwt
from passlib.context import CryptContext
from sqlalchemy.orm import Session

from ..database.database import User, get_db

logger = logging.getLogger(__name__)

# JWT配置
SECRET_KEY = "your-secret-key-change-in-production"  # 生产环境需要更改
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

# 密码加密
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

class AuthService:
    def __init__(self):
        self.secret_key = SECRET_KEY
        self.algorithm = ALGORITHM
        self.access_token_expire_minutes = ACCESS_TOKEN_EXPIRE_MINUTES
    
    def verify_password(self, plain_password: str, hashed_password: str) -> bool:
        """验证密码"""
        return pwd_context.verify(plain_password, hashed_password)
    
    def get_password_hash(self, password: str) -> str:
        """生成密码哈希"""
        return pwd_context.hash(password)
    
    def create_access_token(self, data: Dict[str, Any], expires_delta: Optional[timedelta] = None) -> str:
        """创建访问令牌"""
        to_encode = data.copy()
        if expires_delta:
            expire = datetime.utcnow() + expires_delta
        else:
            expire = datetime.utcnow() + timedelta(minutes=self.access_token_expire_minutes)
        
        to_encode.update({"exp": expire})
        encoded_jwt = jwt.encode(to_encode, self.secret_key, algorithm=self.algorithm)
        return encoded_jwt
    
    def verify_token(self, token: str) -> Optional[Dict[str, Any]]:
        """验证令牌"""
        try:
            payload = jwt.decode(token, self.secret_key, algorithms=[self.algorithm])
            return payload
        except JWTError as e:
            logger.warning(f"JWT验证失败: {e}")
            return None
    
    def authenticate_user(self, db: Session, username: str, password: str) -> Optional[User]:
        """用户认证"""
        try:
            user = db.query(User).filter(User.username == username).first()
            if not user:
                return None
            
            if not self.verify_password(password, user.hashed_password):
                return None
            
            return user
        except Exception as e:
            logger.error(f"用户认证失败: {e}")
            return None
    
    def create_user(self, db: Session, username: str, email: str, password: str, 
                   full_name: Optional[str] = None) -> Optional[User]:
        """创建用户"""
        try:
            # 检查用户名是否已存在
            existing_user = db.query(User).filter(
                (User.username == username) | (User.email == email)
            ).first()
            
            if existing_user:
                return None
            
            # 创建新用户
            hashed_password = self.get_password_hash(password)
            user = User(
                username=username,
                email=email,
                full_name=full_name or username,
                hashed_password=hashed_password,
                is_active=True,
                created_at=datetime.utcnow()
            )
            
            db.add(user)
            db.commit()
            db.refresh(user)
            
            logger.info(f"创建用户成功: {username}")
            return user
            
        except Exception as e:
            logger.error(f"创建用户失败: {e}")
            db.rollback()
            return None
    
    def get_user_by_username(self, db: Session, username: str) -> Optional[User]:
        """根据用户名获取用户"""
        try:
            return db.query(User).filter(User.username == username).first()
        except Exception as e:
            logger.error(f"获取用户失败: {e}")
            return None
    
    def get_user_by_id(self, db: Session, user_id: int) -> Optional[User]:
        """根据ID获取用户"""
        try:
            return db.query(User).filter(User.id == user_id).first()
        except Exception as e:
            logger.error(f"获取用户失败: {e}")
            return None
    
    def update_user(self, db: Session, user_id: int, **kwargs) -> Optional[User]:
        """更新用户信息"""
        try:
            user = db.query(User).filter(User.id == user_id).first()
            if not user:
                return None
            
            for key, value in kwargs.items():
                if hasattr(user, key) and value is not None:
                    if key == "password":
                        user.hashed_password = self.get_password_hash(value)
                    else:
                        setattr(user, key, value)
            
            user.updated_at = datetime.utcnow()
            db.commit()
            db.refresh(user)
            
            logger.info(f"更新用户成功: {user.username}")
            return user
            
        except Exception as e:
            logger.error(f"更新用户失败: {e}")
            db.rollback()
            return None
    
    def delete_user(self, db: Session, user_id: int) -> bool:
        """删除用户"""
        try:
            user = db.query(User).filter(User.id == user_id).first()
            if not user:
                return False
            
            db.delete(user)
            db.commit()
            
            logger.info(f"删除用户成功: {user.username}")
            return True
            
        except Exception as e:
            logger.error(f"删除用户失败: {e}")
            db.rollback()
            return False
    
    def get_all_users(self, db: Session, skip: int = 0, limit: int = 100):
        """获取所有用户（分页）"""
        try:
            return db.query(User).offset(skip).limit(limit).all()
        except Exception as e:
            logger.error(f"获取用户列表失败: {e}")
            return []
    
    def get_user_count(self, db: Session) -> int:
        """获取用户总数"""
        try:
            return db.query(User).count()
        except Exception as e:
            logger.error(f"获取用户总数失败: {e}")
            return 0
    
    def toggle_user_status(self, db: Session, user_id: int) -> Optional[User]:
        """切换用户激活状态"""
        try:
            user = db.query(User).filter(User.id == user_id).first()
            if not user:
                return None
            
            user.is_active = not user.is_active
            user.updated_at = datetime.utcnow()
            db.commit()
            db.refresh(user)
            
            status = "激活" if user.is_active else "禁用"
            logger.info(f"{status}用户成功: {user.username}")
            return user
            
        except Exception as e:
            logger.error(f"切换用户状态失败: {e}")
            db.rollback()
            return None

# 全局实例
auth_service = AuthService()
